package cn.kgc.common.security.filter;

import cn.hutool.core.util.StrUtil;

import cn.kgc.common.constant.RedisPrefix;
import cn.kgc.common.constant.ResultConstant;
import cn.kgc.common.util.JwtUtil;
import cn.kgc.common.util.RedisUtil;
import cn.kgc.common.util.ResponseUtil;
import cn.kgc.common.vo.Result;
import cn.kgc.api.entity.CustomerUser;
import cn.kgc.api.entity.Users;
import cn.kgc.api.service.UsersService;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * @Author: kgc
 * @Date: 2024-04-09
 * @Description: 鉴权的过滤器
 * @Version: v1.0
 */
public class TokenAuthorityFilter extends OncePerRequestFilter {

    private UsersService usersService;
    private RedisUtil redisUtil;

    public TokenAuthorityFilter(UsersService usersService,RedisUtil redisUtil){
        this.usersService=usersService;
        this.redisUtil=redisUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        //登录请求直接放行
        if("/users/login".equals(request.getRequestURI())){
            filterChain.doFilter(request,response);
        }
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
        if(authentication!=null){
            SecurityContextHolder.getContext().setAuthentication(authentication);
            filterChain.doFilter(request,response);
        }else{
            Result result = Result.builder()
                    .code(ResultConstant.NO_PERMISSION.getCode())
                    .message(ResultConstant.NO_PERMISSION.getMessage())
                    .build();
            ResponseUtil.out(response,result);
        }
    }
    /**
     * 获取当前令牌对应的认证
     * @param request
     * @return
     */
    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        String token = request.getHeader("token");
        //令牌为空,没有任何权限
        if(StrUtil.isBlank(token)){
            return null;
        }
        //解析令牌信息
        String userId = JwtUtil.getUserId(token);
        //根据用户ID获得用户的信息
        Users sysUser = usersService.getById(userId);
        //获得用户对应的权限的信息
        List<SimpleGrantedAuthority> authorities=
                (List<SimpleGrantedAuthority>) redisUtil.get(RedisPrefix.SYSTEM_USER_PERMS+userId);
        //封装用户信息
        CustomerUser customerUser=new CustomerUser(sysUser, Collections.emptyList());
        //返回认证信息
        return new UsernamePasswordAuthenticationToken(customerUser,null,authorities);
    }
}